"""
Tag Management API Router
标签管理API路由
"""

import uuid
from typing import Optional, List, Dict, Any

from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_, or_, func, desc

from ..core.database import get_db
from ..core.logging import error_logger
from ..core.exceptions import (
    TagNotFoundError,
    TagAlreadyExistsError,
    ValidationError,
    PermissionDeniedError,
)
from ..models.user import User
from ..models.content_tag import ContentTag, TagCategory, TagVisibility
from ..models.generated_content import GeneratedContent
from ..services.tag_management_service import TagManagementService
from .auth import get_current_user

router = APIRouter()


@router.post("/")
async def create_tag(
    name: str,
    display_name: Optional[str] = Query(None, description="显示名称"),
    description: Optional[str] = Query(None, description="标签描述"),
    category: str = Query("custom", description="标签分类: content_type, style, subject, color, emotion, technique, scene, custom, ai_generated"),
    color: Optional[str] = Query(None, description="标签颜色 (#RRGGBB)"),
    icon: Optional[str] = Query(None, description="图标标识"),
    visibility: str = Query("public", description="可见性: public, private, system"),
    language: str = Query("zh-CN", description="语言代码"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """创建标签"""
    try:
        tag_service = TagManagementService(db)
        
        # 验证标签名称
        if not name or len(name.strip()) == 0:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="标签名称不能为空"
            )
        
        # 验证用户权限（只有管理员可以创建系统标签）
        if visibility == "system" and not current_user.is_admin:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="无权限创建系统标签"
            )
        
        # 创建标签
        tag = await tag_service.create_tag(
            user=current_user,
            name=name.strip(),
            display_name=display_name,
            description=description,
            category=category,
            color=color,
            icon=icon,
            visibility=visibility,
            language=language
        )
        
        return {
            "success": True,
            "data": {
                "id": str(tag.id),
                "name": tag.name,
                "display_name": tag.display_name,
                "description": tag.description,
                "category": tag.category,
                "color": tag.color,
                "icon": tag.icon,
                "visibility": tag.visibility,
                "language": tag.language,
                "usage_count": tag.usage_count,
                "content_count": tag.content_count,
                "is_system": tag.is_system,
                "is_active": tag.is_active,
                "created_at": tag.created_at.isoformat(),
            },
            "message": "标签创建成功"
        }
        
    except TagAlreadyExistsError as e:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=str(e)
        )
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "create_tag",
                "user_id": str(current_user.id),
                "name": name,
                "category": category
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="标签创建失败，请稍后重试"
        )


@router.get("/")
async def list_tags(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(50, ge=1, le=200, description="每页数量"),
    category: Optional[str] = Query(None, description="分类筛选"),
    visibility: Optional[str] = Query(None, description="可见性筛选"),
    search: Optional[str] = Query(None, description="搜索关键词"),
    include_system: bool = Query(True, description="是否包含系统标签"),
    sort_by: Optional[str] = Query("usage_count", description="排序字段"),
    sort_order: Optional[str] = Query("desc", description="排序方向: asc, desc"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """获取标签列表"""
    try:
        tag_service = TagManagementService(db)
        
        # 构建查询条件
        filters = {}
        
        if category:
            filters["category"] = category
        if visibility:
            filters["visibility"] = visibility
        if search:
            filters["search"] = search
        if not include_system:
            filters["is_system"] = False
        
        # 获取标签列表
        result = await tag_service.list_tags(
            page=page,
            page_size=page_size,
            filters=filters,
            sort_by=sort_by,
            sort_order=sort_order
        )
        
        # 格式化返回数据
        items = []
        for tag in result["items"]:
            items.append({
                "id": str(tag.id),
                "name": tag.name,
                "display_name": tag.display_name,
                "description": tag.description,
                "category": tag.category,
                "color": tag.color,
                "icon": tag.icon,
                "visibility": tag.visibility,
                "language": tag.language,
                "usage_count": tag.usage_count,
                "content_count": tag.content_count,
                "is_system": tag.is_system,
                "is_active": tag.is_active,
                "created_at": tag.created_at.isoformat(),
                "last_used_at": tag.last_used_at.isoformat() if tag.last_used_at else None,
            })
        
        return {
            "success": True,
            "data": {
                "items": items,
                "total": result["total"],
                "page": page,
                "page_size": page_size,
                "total_pages": result["total_pages"],
                "has_next": result["has_next"],
                "has_prev": result["has_prev"],
            }
        }
        
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "list_tags",
                "user_id": str(current_user.id),
                "filters": locals().get("filters", {})
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取标签列表失败，请稍后重试"
        )


@router.get("/categories")
async def get_tag_categories(
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """获取标签分类列表"""
    try:
        # 获取所有分类及其统计
        result = await db.execute(
            select(
                ContentTag.category,
                func.count(ContentTag.id).label('tag_count'),
                func.sum(ContentTag.usage_count).label('total_usage')
            ).where(
                and_(
                    ContentTag.is_active == True,
                    or_(
                        ContentTag.visibility == "public",
                        ContentTag.visibility == "system"
                    )
                )
            ).group_by(ContentTag.category).order_by(desc('total_usage'))
        )
        
        categories = result.all()
        
        # 格式化分类数据
        category_list = []
        for category, tag_count, total_usage in categories:
            category_list.append({
                "category": category,
                "display_name": get_category_display_name(category),
                "tag_count": tag_count,
                "total_usage": int(total_usage or 0),
                "description": get_category_description(category)
            })
        
        return {
            "success": True,
            "data": category_list
        }
        
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "get_tag_categories",
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取标签分类失败，请稍后重试"
        )


@router.get("/{tag_id}")
async def get_tag(
    tag_id: str,
    include_contents: bool = Query(False, description="是否包含关联内容"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """获取标签详情"""
    try:
        tag_service = TagManagementService(db)
        
        # 获取标签
        tag = await tag_service.get_tag(
            uuid.UUID(tag_id),
            current_user
        )
        
        if not tag:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="标签不存在或无权限访问"
            )
        
        result = {
            "success": True,
            "data": {
                "id": str(tag.id),
                "name": tag.name,
                "display_name": tag.display_name,
                "description": tag.description,
                "category": tag.category,
                "color": tag.color,
                "icon": tag.icon,
                "visibility": tag.visibility,
                "language": tag.language,
                "translations": tag.translations or {},
                "synonyms": tag.synonyms or [],
                "keywords": tag.keywords or [],
                "usage_count": tag.usage_count,
                "content_count": tag.content_count,
                "is_system": tag.is_system,
                "is_active": tag.is_active,
                "slug": tag.slug,
                "created_at": tag.created_at.isoformat(),
                "updated_at": tag.updated_at.isoformat(),
                "last_used_at": tag.last_used_at.isoformat() if tag.last_used_at else None,
            }
        }
        
        # 包含关联内容
        if include_contents:
            content_result = await db.execute(
                select(GeneratedContent).where(
                    and_(
                        GeneratedContent.content_tags.any(ContentTag.id == tag.id),
                        GeneratedContent.user_id == current_user.id,
                        GeneratedContent.is_deleted == False
                    )
                ).order_by(GeneratedContent.created_at.desc()).limit(20)
            )
            contents = content_result.scalars().all()
            
            result["data"]["contents"] = [
                {
                    "id": str(content.id),
                    "title": content.title,
                    "content_type": content.content_type,
                    "format": content.format,
                    "status": content.status,
                    "thumbnail_url": content.thumbnail_url,
                    "file_size_readable": content.file_size_readable,
                    "is_favorite": content.is_favorite,
                    "created_at": content.created_at.isoformat(),
                }
                for content in contents
            ]
        
        return result
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "get_tag",
                "tag_id": tag_id,
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取标签详情失败，请稍后重试"
        )


@router.put("/{tag_id}")
async def update_tag(
    tag_id: str,
    display_name: Optional[str] = Query(None, description="显示名称"),
    description: Optional[str] = Query(None, description="标签描述"),
    color: Optional[str] = Query(None, description="标签颜色"),
    icon: Optional[str] = Query(None, description="图标标识"),
    visibility: Optional[str] = Query(None, description="可见性"),
    is_active: Optional[bool] = Query(None, description="是否激活"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """更新标签信息"""
    try:
        tag_service = TagManagementService(db)
        
        # 准备更新数据
        update_data = {}
        if display_name is not None:
            update_data["display_name"] = display_name
        if description is not None:
            update_data["description"] = description
        if color is not None:
            update_data["color"] = color
        if icon is not None:
            update_data["icon"] = icon
        if visibility is not None:
            # 验证权限
            if visibility == "system" and not current_user.is_admin:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail="无权限设置为系统标签"
                )
            update_data["visibility"] = visibility
        if is_active is not None:
            update_data["is_active"] = is_active
        
        # 更新标签
        success = await tag_service.update_tag(
            uuid.UUID(tag_id),
            current_user,
            update_data
        )
        
        if not success:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="标签不存在或无权限更新"
            )
        
        return {
            "success": True,
            "message": "标签更新成功"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "update_tag",
                "tag_id": tag_id,
                "user_id": str(current_user.id),
                "update_data": update_data
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="标签更新失败，请稍后重试"
        )


@router.delete("/{tag_id}")
async def delete_tag(
    tag_id: str,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """删除标签"""
    try:
        tag_service = TagManagementService(db)
        
        # 删除标签
        success = await tag_service.delete_tag(
            uuid.UUID(tag_id),
            current_user
        )
        
        if not success:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="标签不存在或无权限删除"
            )
        
        return {
            "success": True,
            "message": "标签删除成功"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "delete_tag",
                "tag_id": tag_id,
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="标签删除失败，请稍后重试"
        )


@router.post("/{content_id}/tags")
async def add_content_tags(
    content_id: str,
    tag_ids: List[str],
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """为内容添加标签"""
    try:
        tag_service = TagManagementService(db)
        
        # 转换标签ID列表
        tag_uuids = [uuid.UUID(tag_id) for tag_id in tag_ids]
        
        # 添加标签
        added_count = await tag_service.add_tags_to_content(
            uuid.UUID(content_id),
            tag_uuids,
            current_user
        )
        
        return {
            "success": True,
            "data": {
                "added_count": added_count
            },
            "message": f"成功添加 {added_count} 个标签"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "add_content_tags",
                "content_id": content_id,
                "tag_ids": tag_ids,
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="添加标签失败，请稍后重试"
        )


@router.delete("/{content_id}/tags")
async def remove_content_tags(
    content_id: str,
    tag_ids: List[str],
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """从内容中移除标签"""
    try:
        tag_service = TagManagementService(db)
        
        # 转换标签ID列表
        tag_uuids = [uuid.UUID(tag_id) for tag_id in tag_ids]
        
        # 移除标签
        removed_count = await tag_service.remove_tags_from_content(
            uuid.UUID(content_id),
            tag_uuids,
            current_user
        )
        
        return {
            "success": True,
            "data": {
                "removed_count": removed_count
            },
            "message": f"成功移除 {removed_count} 个标签"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "remove_content_tags",
                "content_id": content_id,
                "tag_ids": tag_ids,
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="移除标签失败，请稍后重试"
        )


@router.get("/content/{content_id}")
async def get_content_tags(
    content_id: str,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """获取内容的标签列表"""
    try:
        # 获取内容
        content_result = await db.execute(
            select(GeneratedContent).where(
                and_(
                    GeneratedContent.id == uuid.UUID(content_id),
                    GeneratedContent.user_id == current_user.id
                )
            )
        )
        content = content_result.scalar_one_or_none()
        
        if not content:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="内容不存在或无权限访问"
            )
        
        # 获取标签
        tags = content.content_tags
        
        # 格式化标签数据
        tag_list = []
        for tag in tags:
            tag_list.append({
                "id": str(tag.id),
                "name": tag.name,
                "display_name": tag.display_name,
                "description": tag.description,
                "category": tag.category,
                "color": tag.color,
                "icon": tag.icon,
                "visibility": tag.visibility,
                "is_system": tag.is_system,
                "usage_count": tag.usage_count,
                "created_at": tag.created_at.isoformat(),
            })
        
        return {
            "success": True,
            "data": {
                "content_id": content_id,
                "tags": tag_list,
                "total_count": len(tag_list)
            }
        }
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "get_content_tags",
                "content_id": content_id,
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取内容标签失败，请稍后重试"
        )


@router.get("/suggestions")
async def get_tag_suggestions(
    query: str = Query(..., description="搜索关键词"),
    category: Optional[str] = Query(None, description="分类筛选"),
    limit: int = Query(10, ge=1, le=50, description="返回数量限制"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """获取标签建议"""
    try:
        tag_service = TagManagementService(db)
        
        # 获取标签建议
        suggestions = await tag_service.get_tag_suggestions(
            query=query,
            category=category,
            limit=limit,
            user=current_user
        )
        
        # 格式化建议数据
        suggestion_list = []
        for tag in suggestions:
            suggestion_list.append({
                "id": str(tag.id),
                "name": tag.name,
                "display_name": tag.display_name,
                "description": tag.description,
                "category": tag.category,
                "color": tag.color,
                "icon": tag.icon,
                "usage_count": tag.usage_count,
                "content_count": tag.content_count,
                "confidence": 100,  # 匹配置信度
            })
        
        return {
            "success": True,
            "data": suggestion_list
        }
        
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "get_tag_suggestions",
                "query": query,
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取标签建议失败，请稍后重试"
        )


# 辅助函数
def get_category_display_name(category: str) -> str:
    """获取分类显示名称"""
    category_names = {
        "content_type": "内容类型",
        "style": "风格",
        "subject": "主题",
        "color": "颜色",
        "emotion": "情感",
        "technique": "技术",
        "scene": "场景",
        "custom": "自定义",
        "ai_generated": "AI生成",
    }
    return category_names.get(category, category)


def get_category_description(category: str) -> str:
    """获取分类描述"""
    category_descriptions = {
        "content_type": "按内容类型分类的标签",
        "style": "按艺术风格分类的标签",
        "subject": "按主题内容分类的标签",
        "color": "按颜色分类的标签",
        "emotion": "按情感表达分类的标签",
        "technique": "按技术手法分类的标签",
        "scene": "按场景类型分类的标签",
        "custom": "用户自定义标签",
        "ai_generated": "由AI自动生成的标签",
    }
    return category_descriptions.get(category, "")


# 导出路由
__all__ = ["router"]